/*
 * An helper task for common an repetitive tasks.
 */

package common;

import client.SvgClientThread;
import java.lang.management.ManagementFactory;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 *
 */
public class Helper
{
    public static final String SVG_WRITER_RMI = "svgWriter";
    public static final String PROCESS_MANAGER_RMI = "processManager";

    public static IProcessManager getProcessManager() {
        IProcessManager processManager = null;
        // waits for remote object avaibility
        Helper.waitForRemoteObjectAvaibility(PROCESS_MANAGER_RMI);
        try
        {
            processManager = (IProcessManager) Naming.lookup(
                    "rmi://localhost:1099/" + PROCESS_MANAGER_RMI);
        }
        catch (Exception ex)
        {
            Logger.getLogger(Helper.class.getName()).log(
                    Level.SEVERE, null, ex);
        }
        return processManager;
    }


    /**
     *
     * @return the running process id
     */
    public static Integer getProcessId()
    {
        String processName = ManagementFactory.getRuntimeMXBean().getName();
        String processId = processName.split("@")[0];
        return Integer.parseInt(processId);
    }

    public static String getProcessRmiAddressPreffix()
    {
        return "rmi://localhost/process";
    }

    /**
     * will look like "rmi://localhost/processX/receiveBuffer"
     * @return the preffix that should be used as RMI address for a process
     */
    public static String getCurrentProcessRmiAddressPreffix()
    {
        return getProcessRmiAddressPreffixFor(getProcessId());
    }

    /**
     * will look like "rmi://localhost/processX/receiveBuffer"
     * @param process
     * @return preffix that should be used as RMI address for the given process
     */
    public static String getProcessRmiAddressPreffixFor(Integer process)
    {
        return getProcessRmiAddressPreffix() + process + "/";
    }

    /**
     * Checks for remote object avaibility and lock until it becomes available
     */
    public static void waitForRemoteObjectAvaibility(String endsWith)
    {
        boolean svgWriterExists = false;
        String[] boundObjects;
        ArrayList<String> boundObjectsArrayList = new ArrayList<String>();

        // checks for remote object avaibility
        do
        {
            try
            {
                boundObjects = Naming.list("rmi://localhost:1099");
                boundObjectsArrayList = new ArrayList<String>(
                        Arrays.asList(boundObjects));
            } catch (RemoteException ex)
            {
                Logger.getLogger(SvgClientThread.class.getName()).log(Level.SEVERE, null, ex);
            } catch (MalformedURLException ex)
            {
                Logger.getLogger(SvgClientThread.class.getName()).log(Level.SEVERE, null, ex);
            }

            for (String boundObject : boundObjectsArrayList)
            {
                if(boundObject.endsWith(endsWith))
                {
                    svgWriterExists = true;
                }
            }
            try
            {
                Thread.sleep(500); // be gentle with the CPU
            } catch (InterruptedException ex)
            {
                Logger.getLogger(SvgClientThread.class.getName()).log(Level.SEVERE, null, ex);
            }
        } while (!svgWriterExists);
    }


    /**
     * Registers running process to the processManager
     */
    public static void registerToProcessManager()
    {
        IProcessManager processManager = getProcessManager();
        try
        {
            processManager.addProcess(getProcessId());
        } catch (RemoteException ex)
        {
            Logger.getLogger(FirstProgram.class.getName()).log(
                    Level.SEVERE, null, ex);
        }
    }
}
